package com.ease.util {

   /**
    * This class provides the contract to respond to
    * asynchronous calls.
    * <p>
    * If the call has completed successfully, then the registered
    * result handler </b>Function</b> is called with the asynchronous
    * call's return-value as its payload.
    * <p>
    * If the call has completed with errors, then the registered
    * fault handler </b>Function</b> is called with <b>Error</b>
    * object, containing the cause of the error, as the payload.
    *
    * @example Demonstrates the use of AsyncCallback:
    * <listing version="3.0">
    *    translator.translate("hello", "fr_FR", new AsyncCallback(onResult, onError));
    *    // ...
    *    private function onResult(result:String):void {
    *       // ...
    *    }
    *    private function onError(error:Error):void {
    *       // ...
    *    }
    * </listing>
    */
   public class AsyncCallback {

      protected var _resultHandler:Function;
      protected var _faultHandler:Function;
      protected var _callContext:Object;

      /**
       * Constructs a <b>AsyncCallback</b> instance with the specified handlers.
       *
       * @param resultHandler
       *    Function that should be called when the request has
       *    completed successfully.
       *    The function signature is:
       *    <code>function(result:Object, callContext:Object=null)</code>
       *
       * @param faultHandler
       *    Function that should be called when the request has
       *    completed with errors.
       *    The function signature is:
       *    <code>function(error:Error, callContext:Object=null)</code>
       *
       * @param callContext
       *    An arbitrary object passed to the result and fault handlers.
       *    Usually used by the caller to pass state across the async call.
       */
      public function AsyncCallback(
         resultHandler:Function, faultHandler:Function = null
         , callContext:Object = null) {
         this._resultHandler = resultHandler;
         this._faultHandler = faultHandler;
         this._callContext = callContext;
      }

      /**
       * Calls the registered result handler <b>Function</b> with the
       * asynchronous call's return value as the payload.
       */
      public function result(data:Object):void {
         /* if callContext is null then call the result only version, just in case
         the callback function is defined w/o the context param.*/
         if (this._callContext != null) {
            this._resultHandler(data, this._callContext);
         } else {
            this._resultHandler(data);
         }
      }

      /**
       * Calls the registered fault handler <code>Function</code> with the
       * <b>Error</b> object, containing the cause of the error, as the payload.
       */
      public function fault(error:Error):void {
         if (this._faultHandler == null) {
            return;
         }

         /* if callContext is null then call the error only version, just in case
         the callback function is defined w/o the context param.*/
         if (this._callContext != null) {
            this._faultHandler(error, this._callContext);
         } else {
            this._faultHandler(error);
         }
      }
   }

}